const express = require('express');
const { Op } = require('sequelize');
const { body, query, param, validationResult } = require('express-validator');
const db = require('../models');
const logger = require('../utils/logger');

const router = express.Router();
const { CodeExample, Lesson } = db;

// 验证中间件
const handleValidation = (req, res, next) => {
  const errors = validationResult(req);
  if (!errors.isEmpty()) {
    return res.status(400).json({
      error: '请求参数验证失败',
      details: errors.array()
    });
  }
  next();
};

// 获取代码示例列表
router.get('/', [
  query('page').optional().isInt({ min: 1 }).withMessage('页码必须是正整数'),
  query('limit').optional().isInt({ min: 1, max: 100 }).withMessage('每页数量必须在1-100之间'),
  query('lessonId').optional().isInt().withMessage('课程ID必须是整数'),
  query('language').optional().isLength({ min: 1 }).withMessage('编程语言不能为空'),
  query('isRunnable').optional().isBoolean().withMessage('可运行状态必须是布尔值'),
  query('search').optional().isLength({ min: 1 }).withMessage('搜索关键词不能为空'),
  query('orderBy').optional().isIn(['title', 'language', 'sortOrder', 'createdAt']).withMessage('排序字段无效'),
  query('order').optional().isIn(['ASC', 'DESC']).withMessage('排序方向无效'),
  handleValidation
], async (req, res) => {
  try {
    const page = parseInt(req.query.page) || 1;
    const limit = parseInt(req.query.limit) || 20;
    const offset = (page - 1) * limit;
    const { lessonId, language, isRunnable, search, orderBy = 'sortOrder', order = 'ASC' } = req.query;

    // 构建查询条件
    const where = {};
    
    if (lessonId) {
      where.lessonId = parseInt(lessonId);
    }
    
    if (language) {
      where.language = language;
    }
    
    if (isRunnable !== undefined) {
      where.isRunnable = isRunnable === 'true';
    }
    
    if (search) {
      where[Op.or] = [
        { title: { [Op.like]: `%${search}%` } },
        { description: { [Op.like]: `%${search}%` } },
        { code: { [Op.like]: `%${search}%` } }
      ];
    }

    const { count, rows } = await CodeExample.findAndCountAll({
      where,
      include: [
        {
          model: Lesson,
          as: 'lesson',
          attributes: ['id', 'title', 'slug']
        }
      ],
      order: [[orderBy, order], ['created_at', 'ASC']],
      limit,
      offset
    });

    res.json({
      data: rows,
      pagination: {
        page,
        limit,
        total: count,
        pages: Math.ceil(count / limit)
      }
    });

  } catch (error) {
    logger.error('获取代码示例列表失败:', error);
    res.status(500).json({ error: '获取代码示例列表失败', details: error.message });
  }
});

// 获取代码示例统计信息
router.get('/stats', async (req, res) => {
  try {
    const stats = await CodeExample.findAll({
      attributes: [
        'language',
        [sequelize.fn('COUNT', sequelize.col('id')), 'count'],
        [sequelize.fn('SUM', sequelize.literal('CASE WHEN is_runnable = true THEN 1 ELSE 0 END')), 'runnableCount']
      ],
      group: ['language']
    });

    const totalExamples = await CodeExample.count();
    const runnableExamples = await CodeExample.count({ where: { isRunnable: true } });
    const languages = await CodeExample.findAll({
      attributes: ['language'],
      group: ['language']
    });

    res.json({
      data: {
        total: totalExamples,
        runnable: runnableExamples,
        languages: languages.map(l => l.language),
        stats
      }
    });

  } catch (error) {
    logger.error('获取代码示例统计失败:', error);
    res.status(500).json({ error: '获取代码示例统计失败' });
  }
});

// 获取可运行的代码示例
router.get('/runnable', [
  query('language').optional().isLength({ min: 1 }).withMessage('编程语言不能为空'),
  handleValidation
], async (req, res) => {
  try {
    const where = { isRunnable: true };
    if (req.query.language) {
      where.language = req.query.language;
    }

    const examples = await CodeExample.findAll({
      where,
      include: [
        {
          model: Lesson,
          as: 'lesson',
          attributes: ['id', 'title', 'slug']
        }
      ],
      order: [['sortOrder', 'ASC']]
    });

    res.json({ data: examples });

  } catch (error) {
    logger.error('获取可运行代码示例失败:', error);
    res.status(500).json({ error: '获取可运行代码示例失败' });
  }
});

// 根据语言获取代码示例
router.get('/language/:language', [
  param('language').isLength({ min: 1 }).withMessage('编程语言不能为空'),
  handleValidation
], async (req, res) => {
  try {
    const examples = await CodeExample.findAll({
      where: { language: req.params.language },
      include: [
        {
          model: Lesson,
          as: 'lesson',
          attributes: ['id', 'title', 'slug']
        }
      ],
      order: [['sortOrder', 'ASC']]
    });

    res.json({ data: examples });

  } catch (error) {
    logger.error('获取语言代码示例失败:', error);
    res.status(500).json({ error: '获取语言代码示例失败' });
  }
});

// 根据课程获取代码示例
router.get('/lesson/:lessonId', [
  param('lessonId').isInt().withMessage('课程ID必须是整数'),
  handleValidation
], async (req, res) => {
  try {
    const codeExamples = await CodeExample.findAll({
      where: { lessonId: req.params.lessonId },
      include: [
        {
          model: Lesson,
          as: 'lesson',
          attributes: ['id', 'title', 'slug']
        }
      ],
      order: [['sortOrder', 'ASC'], ['created_at', 'ASC']]
    });

    res.json({ data: codeExamples });

  } catch (error) {
    logger.error('获取课程代码示例失败:', error);
    res.status(500).json({ error: '获取课程代码示例失败' });
  }
});

// 根据ID获取代码示例详情
router.get('/:id', [
  param('id').isInt().withMessage('代码示例ID必须是整数'),
  handleValidation
], async (req, res) => {
  try {
    const codeExample = await CodeExample.findByPk(req.params.id, {
      include: [
        {
          model: Lesson,
          as: 'lesson',
          attributes: ['id', 'title', 'slug']
        }
      ]
    });

    if (!codeExample) {
      return res.status(404).json({ error: '代码示例不存在' });
    }

    res.json({ data: codeExample });

  } catch (error) {
    logger.error('获取代码示例详情失败:', error);
    res.status(500).json({ error: '获取代码示例详情失败' });
  }
});

// 创建代码示例
router.post('/', [
  body('lessonId').isInt().withMessage('课程ID必须是整数'),
  body('title').notEmpty().withMessage('示例标题不能为空'),
  body('code').notEmpty().withMessage('代码内容不能为空'),
  body('language').notEmpty().withMessage('编程语言不能为空'),
  body('description').optional().isLength({ max: 1000 }).withMessage('描述不能超过1000字符'),
  body('fileName').optional().isLength({ max: 255 }).withMessage('文件名不能超过255字符'),
  body('sortOrder').optional().isInt().withMessage('排序权重必须是整数'),
  body('isRunnable').optional().isBoolean().withMessage('可运行状态必须是布尔值'),
  handleValidation
], async (req, res) => {
  try {
    // 检查课程是否存在
    const lesson = await Lesson.findByPk(req.body.lessonId);
    if (!lesson) {
      return res.status(404).json({ error: '课程不存在' });
    }

    const codeExample = await CodeExample.create(req.body);
    logger.info(`创建代码示例成功: ${codeExample.title} (ID: ${codeExample.id})`);
    
    res.status(201).json({
      message: '代码示例创建成功',
      data: codeExample
    });

  } catch (error) {
    logger.error('创建代码示例失败:', error);
    res.status(500).json({ error: '创建代码示例失败' });
  }
});

// 更新代码示例
router.put('/:id', [
  param('id').isInt().withMessage('代码示例ID必须是整数'),
  body('lessonId').optional().isInt().withMessage('课程ID必须是整数'),
  body('title').optional().notEmpty().withMessage('示例标题不能为空'),
  body('code').optional().notEmpty().withMessage('代码内容不能为空'),
  body('language').optional().notEmpty().withMessage('编程语言不能为空'),
  body('description').optional().isLength({ max: 1000 }).withMessage('描述不能超过1000字符'),
  body('fileName').optional().isLength({ max: 255 }).withMessage('文件名不能超过255字符'),
  body('sortOrder').optional().isInt().withMessage('排序权重必须是整数'),
  body('isRunnable').optional().isBoolean().withMessage('可运行状态必须是布尔值'),
  handleValidation
], async (req, res) => {
  try {
    const codeExample = await CodeExample.findByPk(req.params.id);
    
    if (!codeExample) {
      return res.status(404).json({ error: '代码示例不存在' });
    }

    // 如果更新课程ID，检查课程是否存在
    if (req.body.lessonId && req.body.lessonId !== codeExample.lessonId) {
      const lesson = await Lesson.findByPk(req.body.lessonId);
      if (!lesson) {
        return res.status(404).json({ error: '课程不存在' });
      }
    }

    await codeExample.update(req.body);
    logger.info(`更新代码示例成功: ${codeExample.title} (ID: ${codeExample.id})`);
    
    res.json({
      message: '代码示例更新成功',
      data: codeExample
    });

  } catch (error) {
    logger.error('更新代码示例失败:', error);
    res.status(500).json({ error: '更新代码示例失败' });
  }
});

// 删除代码示例
router.delete('/:id', [
  param('id').isInt().withMessage('代码示例ID必须是整数'),
  handleValidation
], async (req, res) => {
  try {
    const codeExample = await CodeExample.findByPk(req.params.id);
    
    if (!codeExample) {
      return res.status(404).json({ error: '代码示例不存在' });
    }

    await codeExample.destroy();
    logger.info(`删除代码示例成功: ${codeExample.title} (ID: ${codeExample.id})`);
    
    res.json({ message: '代码示例删除成功' });

  } catch (error) {
    logger.error('删除代码示例失败:', error);
    res.status(500).json({ error: '删除代码示例失败' });
  }
});

// 批量创建代码示例
router.post('/batch', [
  body('lessonId').isInt().withMessage('课程ID必须是整数'),
  body('examples').isArray({ min: 1 }).withMessage('示例数组不能为空'),
  body('examples.*.title').notEmpty().withMessage('示例标题不能为空'),
  body('examples.*.code').notEmpty().withMessage('代码内容不能为空'),
  body('examples.*.language').notEmpty().withMessage('编程语言不能为空'),
  handleValidation
], async (req, res) => {
  const transaction = await db.sequelize.transaction();
  
  try {
    const { lessonId, examples } = req.body;

    // 检查课程是否存在
    const lesson = await Lesson.findByPk(lessonId);
    if (!lesson) {
      await transaction.rollback();
      return res.status(404).json({ error: '课程不存在' });
    }

    // 批量创建代码示例
    const codeExamples = [];
    for (let i = 0; i < examples.length; i++) {
      const example = {
        ...examples[i],
        lessonId,
        sortOrder: examples[i].sortOrder || i
      };
      
      const codeExample = await CodeExample.create(example, { transaction });
      codeExamples.push(codeExample);
    }

    await transaction.commit();
    
    logger.info(`批量创建代码示例成功: ${codeExamples.length} 个示例 (课程ID: ${lessonId})`);
    
    res.status(201).json({
      message: '代码示例批量创建成功',
      data: codeExamples,
      count: codeExamples.length
    });

  } catch (error) {
    await transaction.rollback();
    logger.error('批量创建代码示例失败:', error);
    res.status(500).json({ error: '批量创建代码示例失败' });
  }
});

// 批量更新代码示例
router.put('/batch', [
  body('examples').isArray({ min: 1 }).withMessage('示例数组不能为空'),
  body('examples.*.id').isInt().withMessage('代码示例ID必须是整数'),
  body('examples.*.title').optional().notEmpty().withMessage('示例标题不能为空'),
  body('examples.*.code').optional().notEmpty().withMessage('代码内容不能为空'),
  body('examples.*.language').optional().notEmpty().withMessage('编程语言不能为空'),
  handleValidation
], async (req, res) => {
  const transaction = await db.sequelize.transaction();
  
  try {
    const { examples } = req.body;
    const updates = [];

    for (const example of examples) {
      const codeExample = await CodeExample.findByPk(example.id);
      if (!codeExample) {
        await transaction.rollback();
        return res.status(404).json({ 
          error: '代码示例不存在',
          id: example.id
        });
      }

      await codeExample.update(example, { transaction });
      updates.push(codeExample);
    }

    await transaction.commit();
    
    logger.info(`批量更新代码示例成功: ${updates.length} 个示例`);
    
    res.json({
      message: '代码示例批量更新成功',
      data: updates,
      count: updates.length
    });

  } catch (error) {
    await transaction.rollback();
    logger.error('批量更新代码示例失败:', error);
    res.status(500).json({ error: '批量更新代码示例失败' });
  }
});

// 批量删除代码示例
router.delete('/batch', [
  body('ids').isArray({ min: 1 }).withMessage('ID数组不能为空'),
  body('ids.*').isInt().withMessage('代码示例ID必须是整数'),
  handleValidation
], async (req, res) => {
  const transaction = await db.sequelize.transaction();
  
  try {
    const { ids } = req.body;
    
    // 检查所有ID是否存在
    const examples = await CodeExample.findAll({
      where: { id: { [Op.in]: ids } }
    });
    
    if (examples.length !== ids.length) {
      await transaction.rollback();
      return res.status(404).json({ 
        error: '部分代码示例不存在',
        found: examples.length,
        total: ids.length
      });
    }

    await CodeExample.destroy({
      where: { id: { [Op.in]: ids } },
      transaction
    });

    await transaction.commit();
    
    logger.info(`批量删除代码示例成功: ${ids.length} 个示例`);
    
    res.json({
      message: '代码示例批量删除成功',
      count: ids.length
    });

  } catch (error) {
    await transaction.rollback();
    logger.error('批量删除代码示例失败:', error);
    res.status(500).json({ error: '批量删除代码示例失败' });
  }
});

module.exports = router; 